using System;
using System.Threading.Tasks;
using Gj.Galaxy.Logic;
using SimpleJSON;
using Unity.Services.Core;
using UnityEngine;

namespace Gj.DarkLoong
{
    public class DarkLoong
    {

        public static DarkLoong Instance;
        public static DarkLoongSettings settings;

        static DarkLoong()
        {
            settings = LoadSettings();
            Instance = new DarkLoong();
        }

        private static DarkLoongSettings LoadSettings()
        {
            var loadedSettings = (DarkLoongSettings)Resources.Load("DarkLoongSettings", typeof(DarkLoongSettings));
            if (loadedSettings == null)
            {
                loadedSettings = ScriptableObject.CreateInstance<DarkLoongSettings>();
                LogTools.Error("DarkLoongSettings is not exist (Resources)");
            }

            return loadedSettings;
        }

        public static async Task Init()
        {

        }

        public static async Task Login(SocialManager.AuthType type, string channel, GamePlayer player)
        {
            try
            {
                var info = player.Instance;
                JSONObject result;
                switch (type)
                {
                    case SocialManager.AuthType.AppOfflineOauth:
                        result = await Auth.AppOfflineOauth(channel, info.ToString());
                        break;
                    case SocialManager.AuthType.AppOauth:
                        result = await Auth.AppOauth(channel, info["openId"], info["accessToken"]);
                        break;
                    case SocialManager.AuthType.Oauth:
                        result = await Auth.Oauth(channel, info["code"], info["state"]);
                        break;
                    default:
                        result = await Auth.Login(info["username"], info["password"]);
                        break;
                }
                
                var error = Api.GetError(result);
                
                if (error != "")
                {
                    throw new Exception(error);
                }
                else
                {
                    result = result["result"].AsObject;
                    Auth.SessionToken = result["token"];
                    Auth.UserId = result["userId"];
                    Auth.Id = result["id"];
                    player.Instance = result;
                }
            }
            catch (Exception e)
            {
                throw new Exception("exception");
            }
        }
        
        public static async Task Guest(Action<JSONObject> success, Action<string> fail)
        {
            try
            {
                var response = await Auth.Guest();
                LogTools.Data("Guest", "Data", response.ToString());
                var error = Api.GetError(response);
                if (error != "")
                {
                    fail(error);
                }
                else
                {
                    var result = response["result"].AsObject;
                    Auth.SessionToken = result["token"];
                    Auth.UserId = result["userId"];
                    Auth.Id = result["id"];
                    success(result);
                }
            }
            catch (Exception e)
            {
                fail("exception");
                LogTools.Error(e.ToString());
            }
        }
        
        
        public static async Task Token(string token, Action<JSONObject> success, Action<string> fail)
        {
            try
            {
                var response = await Auth.Token(token);
                LogTools.Data("Token", "Data", response.ToString());
                var error = Api.GetError(response);
                if (error != "")
                {
                    fail(error);
                }
                else
                {
                    var result = response["result"].AsObject;
                    Auth.SessionToken = result["token"];
                    Auth.UserId = result["userId"];
                    Auth.Id = result["id"];
                    success(result);
                }
            }
            catch (Exception e)
            {
                fail("exception");
                LogTools.Error(e.ToString());
            }
        }
        
        
        public static async Task Code(string code, Action<JSONObject> success, Action<string> fail)
        {
            try
            {
                var response = await Auth.LoginCode(code);
                LogTools.Data("Code", "Data", response.ToString());
                var error = Api.GetError(response);
                if (error != "")
                {
                    // Debug.LogError("err");
                    fail(error);
                }
                else
                {
                    // Debug.LogError("suc");
                    var result = response["result"].AsObject;
                    Auth.SessionToken = result["token"];
                    Auth.UserId = result["userId"];
                    Auth.Id = result["id"];
                    success(result);
                }
            }
            catch (Exception e)
            {
                fail("exception");
                Debug.LogException(e);
                LogTools.Error(e.ToString());
            }
        }
    }
}